import {fabric} from 'fabric';
import gsApi from '@/api/gsApi';

export default class CanvasManager{
  canvasId = ''
  // 当前地图
  mapName=''
  // 当前的canvas
  canvas=''
  // 当前地图图片
  img=''
  // 拖动地图状态
  moveStatus=false;
  // 编辑地图状态
  editStatus=false;
  // 打点状态
  clickStatus=false;
  //显示实时位置的三角形对象
  locatTri;
  //手动打点的圆形对象
  positionCircle='';

// 点计画布交互产生的暂存数据
  tempPosition;

  constructor({canvasId,mapName},opt){
    let defaultOpt={
      width: window.innerWidth*0.38,
      height: window.innerHeight-300,
      isDrawingMode: false,
      selection: false, // 是否启用组选择
      devicePixelRatio: true, // Retina 高清屏 屏幕支持
      allowTouchScrolling:false
    }
    Object.assign(defaultOpt, opt);
    this.canvasId=canvasId;
    this.mapName=mapName;

    // 这一步必须要在存在DOM 时候执行，所以一般放在 VUE 的 mounted 事件里
    this.canvas = new fabric.Canvas(canvasId,defaultOpt);

    this.__init();
  }

  __init(){
    // 加载图片
    this.__loadImg(this.mapName);
  }

  reloadImg(mapName){
    // 清除画布所有的内容
    this.canvas.remove(...this.canvas.getObjects());
    this.__loadImg(mapName);
  }

  /**
   * 清除画布除了地图的元素
   */
  clearObject(){
    this.canvas.remove(...this.canvas.getObjects());
    this.canvas.add(this.img);
  }
  /**
   * 清楚画布的地图
   */
  clearMap(){
    this.canvas.remove(...this.canvas.getObjects());
  }

  /**
   * 清除画布上所有的圆 
   */
  clearObjectCircle(){
    this.canvas.remove(...this.canvas.getObjects('circle'));
  }

  /** 
   * 清除画布上所有的文字
   */
  clearObjectText(){
    this.canvas.remove(...this.canvas.getObjects('text'));
  }
    /**
   * 绘制定点
   * @param point 点完整数据
   * @param imgHeight 地图高度，转换需要
   */
  drawPosition({positionName,dataManager}){
      const position = dataManager.positionMap.get(positionName)
      const imgHeight=this.img.height
      const circle=new fabric.Circle({
        radius: 5,
        fill: '#228B22',
        stroke: '#333333',
        strokeWidth: 0.5,
        left: position.gridX,
        //  记得需要转换坐标系的，canvas 上显示坐标系 和 机器人导航的坐标系
        top: imgHeight-position.gridY,
        selectable: false,
        hasBorders: false,
        hasControls: false,
        originX: 'center',
        originY: 'center',
        hoverCursor: 'default',     //这个hoverCursor里可填的值和css里的鼠标指针样式的一样，默认是十字指针
      })
      var text = new fabric.Text(positionName, { 
        fontSize:5,
        left: position.gridX-6, 
        top: imgHeight-position.gridY-11,
        textAlign: 'center',
        selectable: false,
        hoverCursor: 'default'
      });
      this.canvas.add(text);
      if(positionName=='Origin'){
        circle.set('fill','#FF8C00');
      }
      this.canvas.add(circle);
}
// 绘制当前位置点
drawCurrentPosition(point){
    let imgHeight = this.img.height;
    this.circle=new fabric.Circle({
      radius: 5,
      fill: 'red',
      stroke: '#333333',
      strokeWidth: 0.5,
      angle:point.angle,
      left: point.gridPosition.x,
      //  记得需要转换坐标系的，canvas 上显示坐标系 和 机器人导航的坐标系
      top: imgHeight-point.gridPosition.y,
      selectable: false,
      hasBorders: false,
      hasControls: false,
      originX: 'center',
      originY: 'center',
    })
    // console.log(circle);
    this.canvas.add(this.circle);
}

  // 这里是异步加载的要注意处理时许的问题
  __loadImg(mapName){
    // 加载某张地图，就设为当前地图
    this.mapName = mapName;
    const imgUrl=gsApi.getMapPngUrl(mapName);
    new fabric.Image.fromURL(imgUrl,oImg=>{
      oImg.id = mapName
      oImg.evented = false
      this.img=oImg
      this.canvas.add(this.img);
      this.zoomTofit()
    })
  }


  /**
   * 调整画布缩放平移
   */
  zoomTofit(){
    // 先还原缩放比例与位置
    this.canvas.setZoom(1)
    this.canvas.absolutePan({ x: 0, y: 0 })
    // 遍历所有对对象，获取最小坐标，最大坐标,即四个角的坐标
    const objects = this.canvas.getObjects()
    let rect, minX, minY, maxX, maxY
    if (objects.length > 0) {
      rect = objects[0].getBoundingRect()
      minX = rect.left
      minY = rect.top
      maxX = rect.left + rect.width
      maxY = rect.top + rect.height
    } else {
      return
    }
    // 计算平移坐标,居中
    const panX = (maxX - minX - this.canvas.width) / 2 + minX
    const panY = (maxY - minY - this.canvas.height) / 2 + minY
    // 开始平移
    this.canvas.absolutePan({ x: panX, y: panY })
    // 计算缩放比例
    const zoom = Math.min(this.canvas.width / (maxX - minX), this.canvas.height / (maxY - minY))
    // 计算缩放中心
    const zoomPoint = new fabric.Point(this.canvas.width / 2, this.canvas.height / 2)
    // 开始缩放
    this.canvas.zoomToPoint(zoomPoint, zoom)
  }

  /**
   * 返回一个fabric.Circle
   * @param x
   * @param y
   * @param radius
   * @param color
   */
  getCircleElement({x,y,radius,color}) {
    return new fabric.Circle({
      radius: radius,
      fill: color,
      stroke: '#333333',
      strokeWidth: 0.5,
      left: x,
      top: y,
      selectable: false,
      hasBorders: false,
      hasControls: false,
      originX: 'center',
      originY: 'center',
    })
  }

}
